
--需要用到前面的封装和继承
Object ={age =18};

function Object:new() --这里相当于为Object声明了一个自带Objcet参数的函数 函数名叫做new
    --声明本地对象
    local newObj ={}

   --self == Object表 把类自身的方法和属性设置为元表的__index元方法
    self.__index = self;

    --这样后子表设置元表之后 如果子表没有相关属性就会去元表找
    setmetatable(newObj,self)

    return newObj;
end

--继承 需要到封装的创建对象的方法

function Object:subClass(className)

    --从大G表创建键值对
    _G[className] = {}

    local subObj = _G[className]

  --实现base方法 相当于subObj.base是self
    subObj.base = self;
    --定向
    self.__index =self


    setmetatable(subObj,self)

end

---多态 :形似而神不似

Object:subClass("GameObject")
GameObject.posX = 0;
GameObject.posY = 0;
function GameObject:Move()
    self.posX = self.posX + 1
    self.posY = self.posY + 1
    print(self.posX)
    print(self.posY)
end

--继承使用
GameObject:subClass("Player")

function Player:Move()
    --self.base是GameObject 因此会出现将基类传入表之中 造成多次执行基类的方法 
    --self.base:Move() --但是这样写是可以的 只需要让posX 和 posY在new的时候给到新实例即可    
        
    --因此需要指明对象 slef是调用者
    self.base.Move(self)
end

local p1 = Player:new()
p1:Move() 
print("---------------------------")
p1:Move() 
print("---------------------------")
p1:Move() 
print("---------------------------")
local p2 = Player:new()
p2:Move() 
print("---------------------------")
p2:Move() 